import ply.lex as lex

from memory import ESP, EBP

reserved = {
    'mov' : 'MOV',
    'afc' : 'AFC',
    'add' : 'ADD',
    'and' : 'AND',
    'xor' : 'XOR',
    'or'  : 'OR',
    'not' : 'NOT',
    'sub' : 'SUB',
    'mul' : 'MUL',
    'cmp' : 'CMP',
    'store' : 'STORE',
    'load' : 'LOAD',
    'push' : 'PUSH',
    'pop' : 'POP',
    'jmp' : 'JMP',
    'jeq' : 'JEQ',
    'jne' : 'JNE',
    'jlt' : 'JLT',
    'jle' : 'JLE',
    'jgt' : 'JGT',
    'jge' : 'JGE',
    'leave' : 'LEAVE',
    'call' : 'CALL'
}

tokens = [
   'LABEL',
   'LPAREN',
   'RPAREN',
   'REGISTER',
   'CONSTANT',
   'SHARP',
   'NEWLINE',
   'COLON'
] + list(reserved.values())

# Regular expression rules for simple tokens
t_LPAREN  = r'\('
t_RPAREN  = r'\)'
t_SHARP   = r'\#'
t_NEWLINE = r'\n+'
t_COLON   = r':'

def t_REGISTER(t):
    r'([rR]\d+)|(ebp)|(esp)'
    if t.value == "ebp":
        t.value = EBP
    elif t.value == "esp":
        t.value = ESP
    else:
        t.value = int(t.value[1:])
    return t

def t_ID(t):
    r'[a-z]+'
    t.type = reserved.get(t.value, 'LABEL')
    return t

def t_CONSTANT(t):
    r'[+-]?\d+'
    t.value = int(t.value)
    return t

def t_LABEL(t):
    r'[a-zA-Z0-9_]+'
    return t

# A string containing ignored characters (spaces and tabs)
t_ignore  = ' \t'

# Error handling rule
def t_error(t):
    print "Illegal characters '%s'" % t.value
    t.lexer.skip(1)

# Build the lexer
lexer = lex.lex()
